-
-
Notifications
You must be signed in to change notification settings - Fork 273
refactor(ramps): streamline RampsController reset and abort logic #7818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
cursor review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
| if (resource) { | ||
| (resource as Record<string, unknown>)[field] = value; | ||
| } | ||
| (state as Record<string, unknown>)[resourceType] = next; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Race condition in resource field updates can lose data
High Severity
The refactored #updateResourceField method reads this.state[resourceType] outside the update() callback, creates a new object with the updated field, then replaces the entire resource inside the callback. This creates a race condition: if another update() modifies any property of the resource (like data or selected) between capturing the snapshot and executing the callback, those changes are overwritten by the stale next object. The old implementation correctly mutated the draft state inside the callback, which is the proper Immer pattern.


Explanation
Refactors region-dependent reset behavior into a single helper and improves abort handling so dependent resources stay in sync.
Changes
DEPENDENT_RESOURCE_KEYSandresetResource()so "reset one resource" is defined once and driven bygetDefaultRampsControllerState().resetDependentResources()to callgetDefaultRampsControllerState()once and loop over the keys instead of many manual assignments.resetResource(state, 'paymentMethods')insetSelectedProviderandsetSelectedTokenso payment methods are fully reset (includingisLoadinganderror), fixing stale loading/error state when changing or clearing provider/token.Draft<RampsControllerState>so they can be used insideupdate()without casts and avoid TS2589.Result
Single source of truth for default/reset state, less duplicated code, and correct clearing of
paymentMethods(and optionallyquotes.selected) on region or selection changes.References
Checklist
Note
Medium Risk
Touches
RampsControllerrequest lifecycle (caching/loading/error updates and abort races) and reset behavior for multiple region-dependent resources, which can affect UI state consistency under concurrency. Changes are well-covered by additional defensive tests but still impact core controller behavior.Overview
Refactors region-dependent state resets to a shared
resetResourcehelper driven bygetDefaultRampsControllerState(), and uses it to fully resetpaymentMethods(includingisLoading/error) when clearing or changing selected provider/token.Hardens request/resource bookkeeping:
PendingRequestnow tracksresourceType, resource field updates become defensive/immutable, andgetCountries()defensively stores[]when the service returns a non-array.Updates tests and changelog to cover the new reset behavior, hydration/refetch expectations, and timing/race-condition scenarios around dependent resources and loading/error state.
Written by Cursor Bugbot for commit 0a1775b. This will update automatically on new commits. Configure here.